using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Drawing;
using System.Drawing.Imaging;
using System.Web.Hosting;
using System.IO;
using System.Web.Security;
using Microsoft.Practices.ServiceLocation;
using MvcCms.Data.Pagination;
using MvcCms.Service.Code.Wiki;
using WikiPlex;
using WikiPlex.Formatting;
using MvcCms.Data;
using MvcCmsSocial.Models.ViewData;
using MvcCmsSocial.Models;
using MvcCms.Service.Cache;
using MvcCms.Service;
using MvcCmsSocial.Service;
using MvcCms.Service.Validation;
using MvcCmsForum.Service;
using MvcCmsWiki.Service;
using MvcCms.Service.Filters;
using MvcCms.Service.Code;

namespace MvcCmsSocial.Controllers
{
    [RedirectToNonSslIfNotAuthenticated(Redirect = true)]
    public class MvcCmsSocialController : MvcCms.Service.Code.BaseClasses.CMSControllerBase
    {
        #region Constructors
        private readonly IWikiEngine _wikiEngine;
        private readonly ICacheService _cacheService;
        private readonly IAccountService _accountService;
        private readonly ISocialService _socialService;
        public MvcCmsSocialController(IWikiEngine wikiEngine,ICacheService cacheService, IAccountService accountService, ISocialService socialService, ICmsService cmsService, IZoneService zoneService)
            : base(cmsService, zoneService, accountService)
        {
            _cacheService = cacheService;
            _wikiEngine = wikiEngine;
            _accountService = accountService;
            _socialService = socialService;
        }
        #endregion

        [CleanUrls]
        public ActionResult ViewProfile(string userName, string page)
        {
            var user = _accountService.GetUser(userName);

            if (user.Portal.PortalID != _cacheService.GetCurrentPortal().PortalID)
            {
                return Redirect("http://www.mvccms.com/");
            }

            if (user == null)
            {
                return Redirect("/social");
            }
            var images = _socialService.ListSocialImages(user.UserID);
            var profilePic = images.Where(i => i.IsProfilePic).FirstOrDefault();
            if (profilePic != null)
            {
                ViewData["ProfilePic"] = profilePic.ImageName;
            }
            else
            {
                ViewData["ProfilePic"] = "nophotoavailable.gif";
            }
            ViewData["PageTitle"] = user.UserName + " at " + _cacheService.GetCurrentPortal().DisplayName;
            int pageNumber = 1;
            if (page != "1")
            {
                pageNumber = int.Parse(page.Replace("page", ""));
                ViewData["PageTitle"] += " Page " + pageNumber;
            }
            ViewData["PageNumber"] = pageNumber;
            var socialData = _socialService.GetSocialData(user.UserID);
            if (socialData != null)
            {
                socialData.AboutMe = _wikiEngine.Render(socialData.AboutMe, GetFormatter());
            }

            var model = new SocialModel
            {
                _User = user,
                _SocialData = socialData,
                _Portal = _cacheService.GetCurrentPortal(),
                _Profile = _accountService.GetProfile(user.UserID)
            };
            return View(model);
        }

        public ActionResult Index()
        {
            var model = new SocialModel
            {
                _Portal = _cacheService.GetCurrentPortal(),
                _Users = _accountService.ListUsers()
                            .OrderByDescending(user=>user.CreationDate)
                            .AsPagination(1, 40)
            };
            return View(model);
        }

        public ActionResult Wall(Guid userId, string page)
        {
            var forumService = ServiceLocator.Current.GetInstance<IForumService>();
            var cmsService =  ServiceLocator.Current.GetInstance<ICmsService>();
            var wikiService =  ServiceLocator.Current.GetInstance<IWikiService>();


            ViewData["portalProfileFolderName"] = _cacheService.GetCurrentPortal().Name.ToUrlFormat();
            ViewData["CurrentUserPic"] = "";

            var user = _accountService.GetUser();
            if (user != null)
            {
                if (_socialService.GetProfilePic(user.UserID) == null)
                {
                    ViewData["CurrentUserPic"] = "nophotoavailable.gif";
                }
                else
                {
                    ViewData["CurrentUserPic"] = _socialService.GetProfilePic(user.UserID).ImageName;
                }
            }
            int pageNumber = 1;
            if (page != "1")
            {
                pageNumber = int.Parse(page.Replace("page", ""));
            }
            var model = new SocialModel
            {
                _Comments = cmsService.ListContentComments(userId),
                _User = _accountService.GetUser(userId),
                _Posts = forumService.ListUserPosts(userId),
                _SocialMessages = _socialService.ListSocialMessages(userId, pageNumber, 10),
                _WikiContents = wikiService.GetHistory(userId)
            };
            return View("Wall", "DontUseMaster", model);
        }

        public ActionResult Info(Guid userId)
        {
            var forumService = ServiceLocator.Current.GetInstance<IForumService>();
            ViewData["VoteTotal"] = forumService.GetUserVoteTotal(userId);
            var model = new SocialModel
            {
                _User = _socialService.GetUser(_accountService.GetUser(userId).UserName),
                _Profile = _accountService.GetProfile(userId)
            };
            return View("Info", "DontUseMaster", model);
        }

        public ActionResult Photos(Guid userId)
        {
            ViewData["PortalFolder"] = _cacheService.GetCurrentPortal().Name.ToUrlFormat();

            ViewData["UserName"] = _accountService.GetUser(userId).UserName;
            var model = new SocialModel
            {
                _SocialImages = _socialService.ListSocialImages(userId)
            };
            return View("Photos", "DontUseMaster", model);
        }

        public ActionResult Pager()
        {
            return View();
        }

        [Authorize]
        public ActionResult EditProfile()
        {
            var user = _socialService.GetUser(_accountService.GetUserName());
            var images = _socialService.ListSocialImages(user.UserID);
            var profilePic = images.Where(i => i.IsProfilePic).FirstOrDefault();
            if (profilePic != null)
            {
                ViewData["ProfilePic"] = profilePic.ImageName;
            }
            else
            {
                ViewData["ProfilePic"] = "nophotoavailable.gif";
            }
            var socialData = user.SocialData.FirstOrDefault();
            if (socialData != null)
            {
                socialData.AboutMe = _wikiEngine.Render(socialData.AboutMe, GetFormatter());
            }
            var model = new SocialModel
            {
                _Portal = _cacheService.GetCurrentPortal(),
                _User = user,
                _SocialData = socialData,
                _Profile = _accountService.GetProfile(user.UserID),
                _SocialImages = images
            };
            return View("EditProfile", model);
        }

        [Authorize]
        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult EditProfile(int? x, int? y, int? h, int? w, string imageToCrop, bool dontCrop, bool makeProfile)
        {
            var user = _socialService.GetUser(_accountService.GetUserName());
            var foldername = _cacheService.GetCurrentPortal().Name.ToUrlFormat();
            var path = HostingEnvironment.MapPath("~/Uploadedimages/" + foldername + "/Profiles");

            var bmpIn = (Bitmap)Bitmap.FromFile(Path.Combine(path, imageToCrop));

            if (!x.HasValue || dontCrop)
            {
                h = bmpIn.Height;
                w = bmpIn.Width;
                x = 0;
                y = 0;
            }
            var images = _socialService.ListSocialImages(user.UserID);

            if (images.Where(i => i.IsProfilePic).FirstOrDefault()==null)
            {
                ViewData["ProfilePic"] = "nophotoavailable.gif";
            }
            else
            {
                ViewData["ProfilePic"] = images.Where(i => i.IsProfilePic).FirstOrDefault().ImageName;
            }

            if (makeProfile)
            {
                var currentImage = images.Where(pic=>pic.ImageName.Equals(imageToCrop)).FirstOrDefault();
                if (currentImage !=null)
                {
                    currentImage.IsProfilePic = true;
                    _socialService.EditSocialImage(currentImage);
                    ViewData["ProfilePic"] = imageToCrop;
                }
            }

            var cropedImage = new Bitmap(w.GetValueOrDefault(), h.GetValueOrDefault(), PixelFormat.Format24bppRgb);

            using (Graphics g = Graphics.FromImage(cropedImage))
            {
                Rectangle rec = new Rectangle(0, 0, w.GetValueOrDefault(), h.GetValueOrDefault());
                g.DrawImage(bmpIn, rec, x.GetValueOrDefault(), y.GetValueOrDefault(), w.GetValueOrDefault(), h.GetValueOrDefault(), GraphicsUnit.Pixel);
            }
            bmpIn.Dispose();
            var picPath = Path.Combine(path, imageToCrop);
            cropedImage.Save(picPath, ImageFormat.Jpeg);

            //make thumbnail of cropped image and save to thumbs
            string thumbPath = HostingEnvironment.MapPath("~/Uploadedimages/" + foldername + "/Profiles/thumbs");
            thumbPath = Path.Combine(thumbPath, imageToCrop);
            Files.ResizeImage(picPath, thumbPath, 80, 300, false);

            var socialData = user.SocialData.FirstOrDefault();
            if (socialData != null)
            {
                socialData.AboutMe = _wikiEngine.Render(socialData.AboutMe, GetFormatter());
            }

            var model = new SocialModel
            {
                _Portal = _cacheService.GetCurrentPortal(),
                _User = user,
                _SocialData = socialData,
                _Profile = _accountService.GetProfile(user.UserID),
                _SocialImages = images
            };

            return View("EditProfile", model);

        }

        [Authorize]
        [AcceptVerbs(HttpVerbs.Post)]
        [ValidateInput(false)]
        public ActionResult EditAboutMe(string source)
        {
            var user = _socialService.GetUser(_accountService.GetUserName());

            var socialData = user.SocialData.FirstOrDefault();
            if (socialData == null)
            {
                socialData = new SocialData();
                socialData.AboutMe = source;
                socialData.User = user;
                _socialService.CreateSocialData(socialData);
            }
            else
            {
                socialData.AboutMe = source;
                _socialService.EditSocialData(socialData);
            }
            return RedirectToAction("EditProfile");
        }

        private MacroFormatter GetFormatter()
        {
            var siteRenderers = new IRenderer[]
            {
                new TitleLinkRenderer(Url),
                new TextColorRenderer() ,
                new TextSizeRenderer(),
                new AnyStyleRenderer(),
            };
            IEnumerable<IRenderer> allRenderers = Renderers.All.Union(siteRenderers);
            return new MacroFormatter(allRenderers);
        }
    }
}
